package com.educate.common.filter;

import cn.hutool.core.util.StrUtil;
import com.educate.service.impl.UserDetailServiceImpl;
import com.educate.service.UserService;
import com.educate.util.JwtUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


/**
 * @author yjj
 * @date 2021/11/7
 * @description: 验证处理jwt过滤器
 */
public class JwtAuthenticationFilter extends BasicAuthenticationFilter{
    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private UserService UserService;

    @Autowired
    private UserDetailServiceImpl userDetailsService;

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        String jwt = request.getHeader(jwtUtils.getHeader());
        //如果没有jwt, 放行, 让其交给其他过滤器处理异常
        if(StrUtil.isBlankOrUndefined(jwt)){
            chain.doFilter(request,response);
            return;
        }
        //检验jwt
        Claims claims = jwtUtils.getClaimsByToken(jwt);
        if(claims == null){
            throw new JwtException("token异常");
        }
        if(jwtUtils.isTokenExpired(claims)){
            throw new JwtException("token已过期,请尝试重新登录");
        }

        String username = claims.getSubject();

        //获取用户权限信息
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, null,userDetailsService.getUserAuthority(UserService.getUserInfoByUsername(username).getId()));
        SecurityContextHolder.getContext().setAuthentication(token);
        chain.doFilter(request,response);

    }
}
